import java.awt.Polygon;
import java.util.ArrayList;
import java.util.Map;

import com.speljohan.rsbot.accessors.NPC;
import com.speljohan.rsbot.bot.Bot;
import com.speljohan.rsbot.script.Script;
import com.speljohan.rsbot.script.wrappers.RSCharacter;
import com.speljohan.rsbot.script.wrappers.RSItemTile;
import com.speljohan.rsbot.script.wrappers.RSNPC;
import com.speljohan.rsbot.script.wrappers.RSObject;
import com.speljohan.rsbot.script.wrappers.RSTile;

public class TehGuildFisher extends Script {
	long nextAnti = 0;

	@SuppressWarnings("deprecation")
	public int bank() {
		if (distanceTo(new RSTile(2587, 3420)) > 2) {
			walkPathMM(randomizePath(fixPath2(new RSTile(2587, 3420)), 2, 2),
					17);
			return random(250, 500);
		}
		if (bank.getInterface().isValid()) {
			depositAllExcept(10129);
			return random(5000, 1000);
		}

		final RSObject banker = findObject(2213);
		if (banker == null) {
			return random(250, 500);
		}
		if (atObject(banker, "Use-quickly")) {
			return random(250, 500);
		}
		turnToObject(banker);
		return random(250, 500);
	}

	public int fish() {
		if (bank.getInterface().isValid()) {
			bank.close();
			return random(50, 100);
		}
		final RSNPC fish = getNearestNPCByID(312);
		RSTile fishingSpot;
		if (fish == null) {
			if (random(0, 30) == 15) {
				return -1;
			} else {
				fishingSpot = new RSTile(2599, 3422);
			}
		} else {
			fishingSpot = fish.getLocation();
		}
		if (atTile(fishingSpot, "harpoon")) {
			return random(250, 1000);
		}
		if (distanceTo(fish) > 4) {
			walkPathMM(randomizePath(fixPath2(fishingSpot), 2, 2), 17);
		} else {
			turnToTile(fishingSpot);
		}
		if (atTile(fishingSpot, "harpoon")) {
			return random(250, 1000);
		}

		return random(250, 500);
	}

	@Override
	public RSTile[] fixPath2(int startX, int startY, final int destinationX,
			final int destinationY) { // most credits to aftermath
		double dx, dy;
		final ArrayList<RSTile> list = new ArrayList<RSTile>();

		list.add(new RSTile(startX, startY));
		while (Math.hypot(destinationY - startY, destinationX - startX) > 8) {
			dx = destinationX - startX;
			dy = destinationY - startY;
			final int gamble = random(14, 17);
			while (Math.hypot(dx, dy) > gamble) {
				dx *= .95;
				dy *= .95;
			}
			startX += (int) dx;
			startY += (int) dy;
			list.add(new RSTile(startX, startY));
		}
		list.add(new RSTile(destinationX, destinationY));
		return list.toArray(new RSTile[list.size()]);

	}

	@Override
	public RSTile[] fixPath2(final RSTile tile) {
		return fixPath2(getMyPlayer().getLocation().getX(), getMyPlayer()
				.getLocation().getY(), tile.getX(), tile.getY());
	}

	@Override
	public RSTile[] fixPath2(final RSTile tile, final RSTile tile2) {
		return fixPath2(tile.getX(), tile.getY(), tile2.getX(), tile2.getY());
	}

	@Override
	public String getAuthor() {
		return "Mike_";
	}

	@Override
	public String getName() {
		return "Teh Guild Fisher";
	}

	public RSNPC getNPCAt(final RSTile t) {
		final int[] validNPCs = Bot.getClient().getNPCIndexArray();
		final NPC[] npcs = Bot.getClient().getNPCArray();

		for (final int element : validNPCs) {
			if (npcs[element] == null) {
				continue;
			}
			final RSNPC Monster = new RSNPC(npcs[element]);
			try {
				if (Monster.getLocation().equals(t)) {
					return Monster;
				}
			} catch (final Exception e) {
				e.printStackTrace();
			}
		}
		log("NpcAt: None");
		return null;
	}

	@Override
	public String getScriptCategory() {
		return "Fishing";
	}

	@Override
	public String getScriptDescription() {
		String html = "<html>";
		html += "<head>";
		html += "<style>body{font:12pt arial}</style>";
		html += "</head>";
		html += "<body>";
		html += "Teh Guild Fisher! Fish n shet.";
		html += "</body>";
		html += "</html>";

		return html;
	}

	@Override
	public double getVersion() {
		return 0.01;
	}

	public boolean isInGuild() {
		final int nameX[] = new int[] { 2617, 2616, 2616, 2595, 2592, 2592,
				2589, 2589, 2588, 2588, 2586, 2585, 2585, 2582, 2580, 2579,
				2579, 2580, 2590, 2592, 2606, 2613 };
		final int nameY[] = new int[] { 3401, 3398, 3394, 3394, 3396, 3398,
				3401, 3405, 3406, 3408, 3409, 3410, 3413, 3415, 3415, 3416,
				3423, 3425, 3425, 3424, 3427, 3417 };
		final Polygon name = new Polygon(nameX, nameY, 22);
		if (name.contains(getMyPlayer().getLocation().getX(), getMyPlayer()
				.getLocation().getY())) {
			return true;
		}
		return false;
	}

	@Override
	public int loop() {

		final RSCharacter temp = getMyPlayer().getInteracting();
		RSNPC interacting = null;
		if (temp != null) {
			interacting = getNPCAt(temp.getLocation());
		}
		if (interacting != null) {
			if (interacting.getID() == 403 || interacting.getID() == 404
					|| interacting.getID() == 406) {
				atTile(getMyPlayer().getLocation(), "alk here");
			}
		}
		final RSItemTile itemTile = getGroundItemByID(10129);
		if (!isCarryingItem(10129) && itemTile != null) {
			if (tileOnScreen(itemTile)) {
				log("Recovered gear.");
				atTile(itemTile, "Take");
				return random(500, 750);
			}
		}
		if (getDestination() != null || getMyPlayer().getAnimation() != -1
				|| getMyPlayer().isMoving()) {
			if (System.currentTimeMillis() > nextAnti) {
				moveMouse(random(10, 510), random(10, 330));
				nextAnti = System.currentTimeMillis() + 1000
						* random(random(random(10, 30), 40), 59);
			}
			return random(50, 100);
		}
		if (isInventoryFull() || getMyPlayer().isInCombat()) {
			return bank();
		}
		if (bank.getInterface().isValid()) {
			bank.close();
		}
		if (isCarryingItem(10129) && isInGuild()) {
			return fish();
		}
		if (random(0, 30) == 9) {
			// trick. will logout in around a minute if
			// theres a problem.
			return -1;
		}
		return random(1000, 1500);
	}

	@Override
	public void onFinish() {
	}

	@Override
	public boolean onStart(final Map<String, String> args) {
		return true;
	}

}